home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
mxcode
/
ariawave
/
aria.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-12-04
|
9KB
|
311 lines
/* ARIA.C v0.02 */
#include <go32.h>
#include <dpmi.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <pc.h>
#include "aria.h"
/* Declare global Aria parameters and set them at default values */
volatile unsigned int aria_baseport = 0x290;
volatile unsigned int aria_interrupt = 0x72;
volatile unsigned int aria_irq = 10;
volatile unsigned int aria_packetsize = 512;
volatile unsigned int aria_samplesize = 0;
volatile unsigned int aria_dma = 5;
unsigned short *wave_ptr;
volatile long buffer_ptr=0;
_go32_dpmi_seginfo oldirq_rm, rm_si, oldirq_pm, pm_si;
_go32_dpmi_registers rm_regs;
void aria_putmem (int address, int word)
{
outportw (aria_baseport+4, address);
outportw (aria_baseport+6, word);
}
int aria_getmem (int address)
{
int word;
outportw (aria_baseport+4, address);
word=inportw (aria_baseport+6);
return word;
}
/* Send a command to the Aria DSP */
void aria_sendcmd (unsigned command)
{
unsigned i=65535; /* Set time out counter */
while (i--)
{
if (!(inportw(aria_baseport+2) & 0x8000)) /* Wait until the Aria DSP is */
/* ready to receive a command */
{
outportw (aria_baseport, command); /* Send the command */
return;
}
}
return; /* Time out! */
}
/* Set up for one of the three playback modes. Don't issue this command */
/* while PCM audio channels or synthesizer operators are still active. */
/* Mode 0: 4 mono or 2 stereo PCM audio channels ; no synthesis operators */
/* Mode 1: 2 mono or 1 stereo PCM audio channel(s); 20 synthesis operators */
/* Mode 2: 2 mono or 1 stereo PCM audio channel(s); 32 synthesis operators */
/* The default mode is 2. Mode 1 is meant for simultaneous use with other */
/* DSP applications such as reverb processing, QSOUND, or Aria Listener. */
void aria_set_playback_mode(unsigned mode)
{
disable();
aria_sendcmd (0x06);
aria_sendcmd (mode);
aria_sendcmd (0xffff);
enable();
}
void aria_start_playback()
{
disable();
aria_sendcmd (0x11);
aria_sendcmd (0x00);
aria_sendcmd (0xffff);
enable();
}
void aria_stop_playback()
{
disable();
aria_sendcmd (0x12);
aria_sendcmd (0x00);
aria_sendcmd (0xffff);
enable();
}
/* Reading the parameter format as a hex code the following table applies: */
/* format: 00xy x = sample rate y = data format */
/* 0 : 11.025 kHz 0 : 8-bit mono (default) */
/* 1 : 22.050 kHz 1 : 8-bit stereo */
/* 2 : 44.100 kHz 2 : 16-bit mono */
/* 3 : 16-bit stereo */
/* 4 : ADPCM compressed mono */
/* 5 : ADPCM compressed stereo */
void aria_set_audio_format(unsigned format)
{
/* If playing at 44 kHz is requested we have to set some parameters */
if (format>=32)
{
aria_set_playback_mode (0);
disable();
outportw (aria_baseport+2,0x8a);
enable();
}
disable();
aria_sendcmd (0x03);
aria_sendcmd (format);
aria_sendcmd (0xffff);
enable();
}
/* As Aria operates at default in SB emulation mode, */
/* here we set up for Aria native mode */
void aria_init()
{
int ready=0;
outportw (aria_baseport+2,0xc8); /* Aria init */
aria_putmem (0x6102,0); /* Clear task init flag */
/* Aria DSP Init */
disable();
aria_sendcmd (0x00);
aria_sendcmd (0x00);
aria_sendcmd (0x00);
aria_sendcmd (0x00);
aria_sendcmd (0xffff);
enable();
/* Wait for Aria DSP init to complete */
while (ready != 1)
{
outportw (aria_baseport+4, 0x6102);
ready = inportw (aria_baseport+6);
}
outportw (aria_baseport+2,0xca); /* Complete Aria init */
}
void aria_irqhandler()
{
volatile unsigned short address;
volatile long i;
/* Check interrupt type and exit handler if not generated by Aria */
if (inportw(aria_baseport) != 1)
{
outportb (0xa0,0x20); /* secondary controller EOI */
outportb (0x20,0x20); /* primary controller EOI */
enable();
return;
}
/* Play aria_packetsize words from the sample buffer */
address=0x8000;
address-=aria_packetsize;
address-=aria_packetsize;
address+=aria_getmem (0x6100);
outportw(aria_baseport+4,address);
for (i=0;i<aria_packetsize;i++)
outportw(aria_baseport+6,*(wave_ptr+buffer_ptr+i));
aria_sendcmd (0x10);
aria_sendcmd (0xffff);
buffer_ptr+=aria_packetsize;
/* If at end of sample buffer do a wrap around */
if (buffer_ptr > ((aria_samplesize-aria_packetsize)/2))
buffer_ptr=0;
/* Reset interrupt controllers by sending EOIs (EOI=End Of Interrupt) */
outportb (0xa0,0x20); /* secondary controller EOI */
outportb (0x20,0x20); /* primary controller EOI */
enable();
}
void aria_install_interrupt_handler ()
{
int ret;
disable();
/* Install real mode interrupt handler */
rm_si.pm_offset = (int) aria_irqhandler;
ret = _go32_dpmi_allocate_real_mode_callback_iret(&rm_si, &rm_regs);
if (ret != 0)
{
printf ("cannot allocate real mode callback, error=%04x\n",ret);
exit(1);
}
_go32_dpmi_get_real_mode_interrupt_vector(aria_interrupt, &oldirq_rm);
_go32_dpmi_set_real_mode_interrupt_vector(aria_interrupt, &rm_si);
/* Install protected mode interrupt handler */
pm_si.pm_offset = (int) aria_irqhandler;
ret = _go32_dpmi_allocate_iret_wrapper(&pm_si);
if (ret != 0)
{
printf ("cannot allocate protected mode wrapper, error=%04x\n",ret);
exit(1);
}
pm_si.pm_selector = _go32_my_cs();
_go32_dpmi_get_protected_mode_interrupt_vector (aria_interrupt, &oldirq_pm);
_go32_dpmi_set_protected_mode_interrupt_vector(aria_interrupt, &pm_si);
/* Enable interrupts via Aria's IRQ */
outportw (0xA1,inportb(0xA1) & ~(1<<(aria_irq-8)));
enable();
}
void aria_release_interrupt_handler ()
{
disable();
/* Disable interrupts via Aria's IRQ */
outportw (0xA1,inportb(0xA1) | (1<<(aria_irq-8)));
/* Remove our real mode interrupt handler */
_go32_dpmi_set_real_mode_interrupt_vector(aria_interrupt, &oldirq_rm);
if (rm_si.size != -1)
_go32_dpmi_free_real_mode_callback(&rm_si);
rm_si.size = -1;
/* Remove our protected mode interrupt handler */
if (pm_si.size != -1)
_go32_dpmi_free_iret_wrapper (&pm_si);
pm_si.size = -1;
_go32_dpmi_set_protected_mode_interrupt_vector(aria_interrupt,&oldirq_pm);
enable();
}
/* Resets Aria to defaults */
void aria_reset (unsigned format)
{
/* If Aria was set up for playing at 44 kHz we have to reset this to 22 */
if (format>=32)
{
aria_set_playback_mode (2);
disable();
outportw (aria_baseport+2,0xca);
enable();
}
/* As Aria operates in SB emulation mode at default we have to switch */
/* to SB emulation mode before exiting our application */
outportw (aria_baseport+2,0x40);
}
/* Initializes global variables aria_baseport, aria_irq and aria_dma with */
/* settings found in the ARIA environment parameter */
void aria_getparms ()
{
char *t, *aria;
t = getenv("ARIA");
if (!t)
return;
aria = strdup(t); /* Get a copy */
t = strtok(aria, " \t"); /* Parse the ARIA parameter */
while (t) {
switch (t[0]) {
case 'A':
case 'a':
/* I/O address */
sscanf(t + 1, "%x", &aria_baseport);
break;
case 'I':
case 'i':
/* IRQ */
aria_irq = atoi(t + 1);
break;
case 'D':
case 'd':
/* DMA channel */
aria_dma = atoi(t + 1);
break;
case 'T':
case 't':
/* Version */
break;
default:
printf("Unknown ARIA option %c\n",t[0]);
break;
}
t = strtok(NULL," \t");
}
free(aria);
return;
}